package org.linlinjava.litemall.db.service;

import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import org.linlinjava.litemall.db.dao.LitemallRentOrderChangeMapper;
import org.linlinjava.litemall.db.dao.LitemallRentOrderDetailMapper;
import org.linlinjava.litemall.db.dao.LitemallRentOrderMapper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.util.RentOrderConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Service
public class LitemallRentOrderService {
    @Autowired
    private LitemallRentOrderDetailService rentOrderDetailService;
    @Resource
    private LitemallRentOrderMapper rentOrderMapper;
    @Resource
    private LitemallRentOrderDetailMapper rentOrderDetailMapper;
    @Resource
    private LitemallRentOrderChangeMapper rentOrderChangeMapper;

    public LitemallRentOrder findById(Integer orderId) {
        return rentOrderMapper.selectByPrimaryKey(orderId);
    }

    public void updateById(LitemallRentOrder rentOrder) {
        rentOrder.setUpdateTime(LocalDateTime.now());
        rentOrderMapper.updateByPrimaryKeySelective(rentOrder);
    }

    public LitemallRentOrder findByIdAndUserId(Integer id, Integer userId) {
        LitemallRentOrderExample example = new LitemallRentOrderExample();
        example.or().andIdEqualTo(id).andUserIdEqualTo(userId).andDeletedEqualTo(false);
        return rentOrderMapper.selectOneByExample(example);
    }

    public List<LitemallRentOrder> queryAllByUserId(Integer userId) {
        LitemallRentOrderExample rentOrderExample = new LitemallRentOrderExample();
        rentOrderExample.or().andUserIdEqualTo(userId).andDeletedEqualTo(false);
        return rentOrderMapper.selectByExample(rentOrderExample);
    }


    public int getReturnBooksCount(Integer userId) {

        return rentOrderMapper.getReturnBooksCount(userId);
    }
    /**
     * 查找租书已收货的订单
     *
     * @param userId
     * @return
     */
    public LitemallRentOrder queryByUserIdAndStatus(Integer userId) {
        LitemallRentOrderExample rentOrderExample = new LitemallRentOrderExample();
        rentOrderExample.or().andUserIdEqualTo(userId).andRentOrderStatusEqualTo(RentOrderConstant.STATUS_CONFIRM).andDeletedEqualTo(false);
        return rentOrderMapper.selectOneByExample(rentOrderExample);
    }

    /**
     * 逻辑删除
     *
     * @param id
     */
    public void logicalDeleteById(Integer id) {
        rentOrderMapper.logicalDeleteByPrimaryKey(id);
    }

    /**
     * 查询租借订单
     *
     * @param userId
     * @param status
     * @param page
     * @param limit
     * @param sort
     * @param order
     * @return
     */
    public List<Map<String, Object>> querySelective(Integer userId, Integer status, Integer page, Integer limit, String sort, String order) {
        LitemallRentOrderExample example = new LitemallRentOrderExample();
        LitemallRentOrderExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId).andDeletedEqualTo(false);
        switch (status) {
            case 1:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_WAIT);
                break;
            case 2:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_SHIP);
                break;
            case 3:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_CONFIRM);
                break;
            case 4:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_CANCEL);
                break;
            case 0:
            default:
                break;
        }
        PageHelper.startPage(page, limit);
        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }

        List<LitemallRentOrder> rentOrders = rentOrderMapper.selectByExample(example);
        if (rentOrders == null) {
            return null;
        }
        List<Map<String, Object>> data = new ArrayList<>();
        for (LitemallRentOrder rentOrder : rentOrders) {
            List<LitemallRentOrderDetail> rentOrderDetails = rentOrderDetailService.queryByOid(rentOrder.getId());
            Map<String, Object> orderMap = new HashMap<>();
            orderMap.put("rentOrder", rentOrder);
            orderMap.put("rentOrderStatusText", RentOrderConstant.rentOrderStatusText(rentOrder));
            orderMap.put("rentOrderDetails", rentOrderDetails);
            data.add(orderMap);
        }
        return data;
    }

    public LitemallRentOrder findById(Integer userId, Integer id) {
        LitemallRentOrderExample example = new LitemallRentOrderExample();
        example.or().andIdEqualTo(id).andUserIdEqualTo(userId).andDeletedEqualTo(false);
        return rentOrderMapper.selectOneByExample(example);
    }

    public List<LitemallRentOrder> queryByUIdAndStatusNe(Integer userId) {
        LitemallRentOrderExample example = new LitemallRentOrderExample();
        example.or().andUserIdEqualTo(userId).andRentOrderStatusNotEqualTo(RentOrderConstant.STATUS_CANCEL).andDeletedEqualTo(false);
        return rentOrderMapper.selectByExample(example);
    }

    public LitemallRentOrder queryLastOrder(Integer userId) {
        LitemallRentOrderExample example = new LitemallRentOrderExample();
        example.or().andUserIdEqualTo(userId).andDeletedEqualTo(false);

        List<LitemallRentOrder> rentOrders = rentOrderMapper.selectByExample(example);
        if (rentOrders == null || rentOrders.isEmpty()) {
            return null;
        }
        if (rentOrders.size() > 1) {
            return rentOrders.get(rentOrders.size() - 1);
        } else {
            return rentOrders.get(0);
        }
    }


    /**
     * //查询所有订单状态是否存在未完成的订单
     * @param userId
     * @return
     */
    public boolean queryOrderHaveNoReturnBook(Integer userId) {

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        LitemallRentOrderExample example = new LitemallRentOrderExample();
        example.or().andUserIdEqualTo(userId).andDeletedEqualTo(false)
                .andRentOrderStatusIn(list);
        LitemallRentOrder litemallRentOrder = rentOrderMapper.selectOneByExample(example);

        return litemallRentOrder != null;


    }

    /**
     * 后台根据姓名模糊查询和订单状态查询
     *
     * @param username
     * @param status
     * @param page
     * @param limit
     * @param sort
     * @param order
     * @return
     */
    public List<LitemallRentOrder> querySelective(String username, String rentOrderSn, String start, String end,
                                                  Integer status, Integer page, Integer limit, String sort, String order, String bookName,Integer userId) {
        // 判断作者是否为空
        // todo 去详情页面查出

        List<Integer> idList = new ArrayList<>();
        if (!StringUtils.isEmpty(bookName)) {
            LitemallRentOrderDetailExample detailExample = new LitemallRentOrderDetailExample();
            LitemallRentOrderDetailExample.Criteria exampleCriteria = detailExample.createCriteria();
            exampleCriteria.andNameLike("%" + bookName + "%");
            List<LitemallRentOrderDetail> litemallRentOrderDetails = rentOrderDetailMapper.selectByExample(detailExample);

            if (!CollectionUtils.isEmpty(litemallRentOrderDetails)) {
                idList = litemallRentOrderDetails.stream().map(item -> {
                    Integer rentOrderId = item.getRentOrderId();
                    return rentOrderId;
                }).collect(Collectors.toList());
            } else {
                return new ArrayList<LitemallRentOrder>();
            }

        }


        LitemallRentOrderExample example = new LitemallRentOrderExample();
        LitemallRentOrderExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(username)) {
            criteria.andUserNameLike("%" + username + "%");
        }
        if (ObjectUtil.isNotEmpty(userId)){
            criteria.andUserIdEquals(userId);
        }
        if (!StringUtils.isEmpty(rentOrderSn)) {
            criteria.andRentOrderSnEqualTo(rentOrderSn);
        }
        DateTimeFormatter dft = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        if (!StringUtils.isEmpty(start)) {
            LocalDate localDate = LocalDate.parse(start, dft);
            LocalDateTime startTime = localDate.atStartOfDay();
            criteria.andAddTimeGreaterThanOrEqualTo(startTime);
        }
        if (!StringUtils.isEmpty(end)) {
            LocalDate localDate = LocalDate.parse(end, dft);
            LocalDateTime endTime = localDate.atStartOfDay();
            criteria.andAddTimeLessThanOrEqualTo(endTime);
        }

        if (!CollectionUtils.isEmpty(idList)) {
            criteria.andIdIn(idList);
        }
        switch (status) {
            case 1:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_WAIT);
                break;
            case 2:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_SHIP);
                break;
            case 3:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_CONFIRM);
                break;
            case 4:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_RETURN_WAIT);
                break;
            case 5:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_RETURN_SHIP);
                break;
            case 6:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_CONFIRM_RETURN);
                break;
            case 7:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_CANCEL);
                break;
            case 0:
            default:
                break;
        }
        criteria.andDeletedEqualTo(false);
        PageHelper.startPage(page, limit);
        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }
        return rentOrderMapper.selectByExample(example);
    }

    /**
     * 查询订单详情
     *
     * @param rentOrderId
     * @return
     */
    public Map<String, Object> queryRentOrderDetail(Integer rentOrderId) {
        LitemallRentOrder rentOrder = findById(rentOrderId);
        if (rentOrder == null) {
            return null;
        }
        List<LitemallRentOrderDetail> rentOrderDetails = rentOrderDetailService.queryByOid(rentOrderId);
        Map<String, Object> data = new HashMap<>();
        data.put("rentOrder", rentOrder);
        data.put("rentOrderDetails", rentOrderDetails);
        return data;
    }

    public List<LitemallRentOrderChange> getRentOderLife(Integer orderId) {

        LitemallRentOrderChangeExample example = new LitemallRentOrderChangeExample();
        LitemallRentOrderChangeExample.Criteria criteria = example.createCriteria();
        criteria.andRentOrderIdEqualTo(orderId);
        example.setOrderByClause("rent_order_time_status");

        List<LitemallRentOrderChange> litemallRentOrderChanges = rentOrderChangeMapper.selectByExample(example);
        return litemallRentOrderChanges;

    }

    public List querySelective(Integer userId, String username, String rentOrderSn, String start, String end,
                               Integer status, Integer page, Integer limit, String sort, String order, String bookName) {

        // 判断作者是否为空
        // todo 去详情页面查出

        List<Integer> idList = new ArrayList<>();
        if (!StringUtils.isEmpty(bookName)) {
            LitemallRentOrderDetailExample detailExample = new LitemallRentOrderDetailExample();
            LitemallRentOrderDetailExample.Criteria exampleCriteria = detailExample.createCriteria();
            exampleCriteria.andNameLike("%" + bookName + "%");
            List<LitemallRentOrderDetail> litemallRentOrderDetails = rentOrderDetailMapper.selectByExample(detailExample);

            if (!CollectionUtils.isEmpty(litemallRentOrderDetails)) {
                idList = litemallRentOrderDetails.stream().map(item -> {
                    Integer rentOrderId = item.getRentOrderId();
                    return rentOrderId;
                }).collect(Collectors.toList());
            } else {
                return new ArrayList<LitemallRentOrder>();
            }

        }


        LitemallRentOrderExample example = new LitemallRentOrderExample();
        LitemallRentOrderExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId);
        if (!StringUtils.isEmpty(username)) {
            criteria.andUserNameLike("%" + username + "%");
        }
        if (!StringUtils.isEmpty(rentOrderSn)) {
            criteria.andRentOrderSnEqualTo(rentOrderSn);
        }
        DateTimeFormatter dft = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        if (!StringUtils.isEmpty(start)) {
            LocalDate localDate = LocalDate.parse(start, dft);
            LocalDateTime startTime = localDate.atStartOfDay();
            criteria.andAddTimeGreaterThanOrEqualTo(startTime);
        }
        if (!StringUtils.isEmpty(end)) {
            LocalDate localDate = LocalDate.parse(end, dft);
            LocalDateTime endTime = localDate.atStartOfDay();
            criteria.andAddTimeLessThanOrEqualTo(endTime);
        }

        if (!CollectionUtils.isEmpty(idList)) {
            criteria.andIdIn(idList);
        }
        switch (status) {
            case 1:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_WAIT);
                break;
            case 2:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_SHIP);
                break;
            case 3:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_CONFIRM);
                break;
            case 4:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_RETURN_WAIT);
                break;
            case 5:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_RETURN_SHIP);
                break;
            case 6:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_CONFIRM_RETURN);
                break;
            case 7:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_CANCEL);
                break;
            case 0:
            default:
                break;
        }
        criteria.andDeletedEqualTo(false);
        PageHelper.startPage(page, limit);
        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }

        return rentOrderMapper.selectByExample(example);
    }
}
